import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import aima.search.framework.Successor;
import aima.search.framework.SuccessorFunction;

@SuppressWarnings("unused")
public class IAPrac1SuccessorFunctionSA implements SuccessorFunction {

	private static int ELIMINAR_CONDUCTOR = 0;
	private static int ASIGNAR = 1;
	private static int MOVER = 2;
	private static int INTERCAMBIAR_CONTIGUOS = 3;
	private static int INTERCAMBIAR = 4;
	private static int CREAR_CONDUCTOR = 5;
	private static int ELIMINAR_PASAJERO = 6;
	private static int NUM_OPS = 4;
	
	public List<Successor> getSuccessors(Object aState) {
		List<Successor> successors = new ArrayList<Successor>();
		IAPrac1State estado = (IAPrac1State) aState;
		IAPrac1State nuevoEstado = null;
		
		Vector<Vector<Integer>> conds = (Vector<Vector<Integer>>)estado.getConductores();
		Vector<Integer> pass = (Vector<Integer>)estado.getPasajerosPendientes();
		int nconds = estado.ncond;
		int npass = estado.npas;
		Vector<Integer> cruta = null;
		int nruta;
		String S = null;
		
		Random rand = new Random();
		boolean done = false;
		int op, con, con2, pas, pas2, pos;
		
		while(!done) {
			op = rand.nextInt(NUM_OPS);
			
			con = rand.nextInt(IAPrac1State.K);
			while (conds.get(con) == null) con = rand.nextInt(IAPrac1State.K);
			cruta = (Vector<Integer>)conds.get(con);
			nruta = cruta.size();
			
			con2 = rand.nextInt(IAPrac1State.K);
			while (con2 == con || conds.get(con2) == null) con2 = rand.nextInt(IAPrac1State.K);
			
			if (npass == 0) pas = -1;
			else pas = ((Integer)pass.get(rand.nextInt(npass))).intValue();
			
			if (nruta == 0) pas2 = -1;
			else pas2 = ((Integer)cruta.get(rand.nextInt(nruta))).intValue();

			if (nruta == 0) pos = -1;
			else pos = rand.nextInt(nruta);
			
			nuevoEstado = new IAPrac1State(conds, estado.ncond, pass, estado.npas);
			
			if (op == ELIMINAR_CONDUCTOR && nuevoEstado.eliminarConductor(con)) {
				S = IAPrac1State.ELIMINAR_CONDUCTOR+"-"+con; 
				successors.add(new Successor(S, nuevoEstado));
				done = true;
			}
			else if(op == ASIGNAR && pas != -1 && nuevoEstado.asignarPasajero(con, pas)) {
				S = IAPrac1State.ASIGNAR+"-"+con+"-"+pas;
				successors.add(new Successor(S, nuevoEstado));
				done = true;
			}
			else if(op == MOVER && pas2 != -1) {
				if (nuevoEstado.moverPasajero(con, pas2, con2)) {
					S = IAPrac1State.MOVER+"-"+con+"-"+pas2+"-"+con2;
					successors.add(new Successor(S, nuevoEstado));
					done = true;
				}
			}
			else if(op == INTERCAMBIAR_CONTIGUOS && pos != -1) {
				if (nuevoEstado.switchPasajeros(con, pos)) {
					S = IAPrac1State.INTERCAMBIAR_CONTIGUOS+"-"+con+"-"+pos;
					successors.add(new Successor(S, nuevoEstado));
					done = true;
				}
			}
		}
		
		return successors;
	}
}
